﻿using System;
using System.Linq;
using System.Web.Mvc;
using WeBlog.Interfaces;
using WeBlog.Models;
using WeBlog.Repositories;
using WeBlog.Widgets;

namespace WeBlog.Controllers {	    
    public class WidgetController : ApplicationController
    {
        private readonly WidgetRepository _repository;        

        public WidgetController(IUnitOfWork unitOfWork) 
            : base( unitOfWork )
        {            
            _repository = new WidgetRepository(unitOfWork);
        }

        [ChildActionOnly]
        public ActionResult Bar(int column = 1)
        {
            var model = new WidgetBarModel
            {
                Column = column,
                WidgetIds = _repository.FindAll()
                            .Where(x => x.Column == column)
                            .OrderBy(x => x.Row)
                            .Select(x => x.WidgetId),
                RegisteredWidgets = Application.WidgetManager.RegisteredWidgets
                                    .OrderBy( x => x.Name )
                                    .Select(x => new SelectListItem { Text = x.Name, Value = x.Name })
            };
            return PartialView( model );
        }

        [ChildActionOnly]
        public ActionResult View(int id)
        {
            var setting = _repository.Find( id );            
            IWidget widget = Application.WidgetManager.FindBySlug(setting.Name);

            var model = new WidgetViewModel {
                Id = setting.WidgetId,
                Title = setting.Title,
                ViewName = String.Format("~/Widgets/{0}/View.cshtml", widget.Name),
                ViewData = widget.ViewModel,
                IsEditable = widget.IsEditable
            }; 

            return PartialView(model);
        }

        [WeBlogAuthorize(Roles = Role.Admin)]
        public JsonResult Delete(int id)
        {
			try {
                Widget widget = _repository.Find(id);
                _repository.Remove(widget);
                UnitOfWork.Commit();
				return Json(new JsonResponse
				{
					Success = true
				});
			}
			catch (Exception ex) {
				return Json(new JsonResponse
				{
					Message = ex.Message,
					Success = false
				});
			}
		}

        [WeBlogAuthorize(Roles = Role.Admin)]
        public ActionResult Add(string slug, int column)
        {
            IWidget widget = Application.WidgetManager.FindBySlug(slug);
            var settings = new Widget();
            settings.Title = widget.Name;
            settings.Name = widget.Name;
            settings.Column = column;      
            _repository.Add(settings);
            UnitOfWork.Commit();
            return RedirectToAction("Index", "Post");
        }

        [WeBlogAuthorize(Roles = Role.Admin)]
        public ActionResult Edit(int id)
        {
            Widget widget = _repository.Find(id);
            return widget == null ? NotFound() : View(widget);
        }

        [HttpPost]
        [WeBlogAuthorize(Roles = Role.Admin)]
        public ActionResult Edit(int id, FormCollection formValues)
        {
            Widget widget = _repository.Find(id);
			if (widget == null) return NotFound();

			UpdateModel(widget);
            UnitOfWork.Commit();
			return View(widget);
		}

        [WeBlogAuthorize(Roles = Role.Admin)]
        public JsonResult SavePosition(int id, int col, int row)
        {
			try {
                var widgets = _repository.FindAll()
                                .Where(x => x.WidgetId != id)
                                .OrderBy(x => x.Row)
                                .Select(x => x.WidgetId).ToList();				

				widgets.Insert(row, id);    

				int index = 0;
				foreach (int key in widgets) {
                    Widget widget = _repository.Find(key);
					if (widget.Row != index) {
						widget.Row = index;                                                                       
					}                    
					index++;
				}
                UnitOfWork.Commit();
				return Json(new JsonResponse { Success = true });
			}
			catch (Exception ex) {
				return Json(new JsonResponse { Success = false, Message = ex.Message });
			}
		}
	}
}
